package com.fh.service.cuijimanage;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fh.mapper.loan.CallLoanCallInfoMapper;
import com.fh.mapper.loan.CallLoanContactsInfoMapper;
import com.fh.mapper.loan.CallLoanDeviceInfoMapper;
import com.fh.mapper.loan.CallLoanInfoMapper;
import com.fh.mapper.loan.CallLoanUserCardInfoMapper;
import com.fh.model.loan.CallLoanCallInfo;
import com.fh.model.loan.CallLoanContactsInfo;
import com.fh.model.loan.CallLoanDeviceInfo;
import com.fh.model.loan.CallLoanDeviceInfoExample;
import com.fh.model.loan.CallLoanUserCardInfo;
import com.fh.model.loan.HisOverdueBillInfo;
import com.fh.util.HttpUtils;
import com.fh.util.PhoneUtil;

/**
 * Created by dell、 on 2017/6/15.
 */
@Service
public class HisOverdueBillInfoService {
    private Logger logger = LoggerFactory.getLogger(HisOverdueBillInfoService.class);

    @Autowired
    private CallLoanDeviceInfoMapper callLoanDeviceInfoMapper;

    @Autowired
    private CallLoanInfoMapper mapper;

    @Autowired
    private CallLoanUserCardInfoMapper cardInfo;

    @Autowired
    private CallLoanContactsInfoMapper contactsInfoMapper;

    @Autowired
    private CallLoanCallInfoMapper callLoanCallInfoMapper;

    //获取历史逾期账单
    public List<HisOverdueBillInfo> findHisOverdueBillInfo(Map map)throws Exception{
        return mapper.findHisOverdueBillInfo(map);
    }
    
    /**
     * 获取最近三天通话记录
     * @param userId
     * @return
     * @author yc
     */
     public List<CallLoanCallInfo> getLast3DaysCallRecord(String userId){
         List<CallLoanCallInfo> list = callLoanCallInfoMapper.selectBy3Day(userId);
         for (CallLoanCallInfo info : list){
             try {
                 Map<String, String> map = PhoneUtil.getPhoneInfo(info.getContMobile());
                 if (map != null){
                     String province = map.get("province");
                     info.setMobileAddress(province);
                 }
            }
            catch (Exception e) {
                logger.error("获取最近三天通话记录====={}", e.getMessage());
            }
         }
         return list;
         
     }

    /**
     * 获取借款人最近的20条通话记录,第一个表
     * @param userId
     * @return
     * @author yc
     */
    public List<CallLoanCallInfo> getLast20CallRecordList(String userId){
        logger.info("获取借款人最近的20条通话记录,第一个表,userId==>{}",userId);
        List<CallLoanCallInfo> list = callLoanCallInfoMapper.selectByTop20(userId);
   /*     Iterator<CallLoanCallInfo> iterator = list.iterator();
        while(iterator.hasNext()){
            CallLoanCallInfo info = iterator.next();
            if (info == null){
                iterator.remove();
            }else{
                try {
                    Map<String, String> map = PhoneUtil.getPhoneInfo(info.getContMobile());
                    if (map != null){
                        String province = map.get("province");
                        info.setMobileAddress(province);
                    }
                }
                catch (Exception e) {
                    logger.error("最近的20条通话记录====={}", e.getMessage());
                }
            }
        }*/
        return list;
    }


    //获取借款人的身份证图片v2.0
    public  CallLoanUserCardInfo  getUserIdCardInfo2(String userId) {
        return cardInfo.selectCardInfoByUserId(userId);
    }

    //获取设备登录信息
    public List<CallLoanDeviceInfo> getDevcieLoginInfo(Integer userId) {
        Map<String,Object> mao = new HashMap<>();
        mao.put("userId",userId);
        List<CallLoanDeviceInfo> callLoanDeviceInfos = callLoanDeviceInfoMapper.findCallLoanDeviceInfoByMap(mao);
        return callLoanDeviceInfos;
    }

    public List<CallLoanContactsInfo> getCallHisBookTop20List(String userId){
      //  List<CallLoanContactsInfo> list = contactsInfoMapper.selectContactsInfoByUserId(userId);
        List<CallLoanContactsInfo> list = setView(contactsInfoMapper.selectByUserId(userId));
        for (CallLoanContactsInfo info : list){
            try {
                Map<String, String> map = PhoneUtil.getPhoneInfo(info.getContactsMobile());
                if (map != null){
                    String province = map.get("province");
                    info.setMobileAddress(province);
                } 
            }
            catch (Exception e) {
                logger.error("用户通讯录前20条====={}", e);
            }
        }
        return list;
    }

    /**
     * 获取用户通讯录前20条 v2.0
     * @param userId
     * @return
     */
    public List<CallLoanContactsInfo> getCallHisBookTop20List2(String userId){
        logger.info("获取用户通讯录前20条,第三个表,userId==>{}",userId);
//        List<CallLoanContactsInfo> list = setView(contactsInfoMapper.selectByUserId(userId));//20493、18535
        List<CallLoanContactsInfo> list = contactsInfoMapper.selectByUserId(userId);//20493、18535
        /*for (CallLoanContactsInfo info : list){
            try {
                Map<String, String> map = PhoneUtil.getPhoneInfo(info.getContactsMobile());
                if (map != null){
                    String province = map.get("province");
                    info.setMobileAddress(province);
                }
            }
            catch (Exception e) {
                logger.error("用户通讯录前20条====={}", e);
            }
        }*/
        return list;
    }

    private List<CallLoanContactsInfo>  setView(List<CallLoanContactsInfo> list){
        List<CallLoanContactsInfo> views = new ArrayList<>();
        Optional<List<CallLoanContactsInfo>> data = Optional.ofNullable(list);
        if(data.isPresent()) {
            LinkedList<CallLoanContactsInfo> linkedList = new LinkedList<>(data.get());
            List<CallLoanContactsInfo> view1 = new ArrayList<>();
            List<CallLoanContactsInfo> view2 = new ArrayList<>();
            /**
             * 第一级：通讯录名称为：丈夫、妻子、老公、老婆、父亲、母亲、爸爸、妈妈
             */
            view1 = data
                .get()
                .stream()
                .filter(x -> {
                    Optional<String> cName = Optional.ofNullable(x.getContactsName());
                    return cName.isPresent()&&cName.get().matches("丈夫|妻子|老公|老婆|父亲|母亲|爸爸|妈妈|老爸|老妈");
                })
                .collect(Collectors.toList());
            /**
             * 第二级：通讯录名称中带有“姐”、“妹”、“哥”、“弟” “儿子”、“女儿”字段
             */
            view2 = data
                    .get()
                    .stream()
                    .filter(
                            x -> {
                                Optional<String> cName = Optional.ofNullable(x.getContactsName());
                               return cName.isPresent()&&cName.get()
                                        .matches("(.*)姐(.*)" +
                                                "|(.*)妹(.*)" +
                                                "|(.*)哥(.*)" +
                                                "|(.*)弟(.*)" +
                                                "|(.*)儿子(.*)" +
                                                "|(.*)女儿(.*)");
                            })
                    .collect(Collectors.toList());
            /**
             * 第三级
             * 优先展示第一级的通讯录名称的号码，其次展示第二级通讯录名称的号码。
             * 如果匹配通讯录数目超过60个，
             * 则同一级别，根据通话次数进行优先级别排序筛选，通话次数多的优先展示；
             * 再次依据最后通话时间筛选，最后通话时间最近的优先展示；
             * 最后依据创建时间排序筛选，即创建时间早的，优先展示。
             */
            view1 = view1.stream()
                    .sorted((x1,x2) -> {
                        Integer a1 = null;
                        Integer a2 = null;
                        try {
                            Optional<String> num1 = Optional.ofNullable(x1.getCallNumber());
                            Optional<String> num2 = Optional.ofNullable(x2.getCallNumber());
                            if(num1.isPresent() && num2.isPresent()){
                                a1 = Integer.parseInt(num1.get());
                                a2 = Integer.parseInt(num2.get());
                            }
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                            logger.error("转整型异常",e);
                        }
                        if (a1!=null){
                            return  a1.compareTo(a2);
                        }else if(a2!=null){
                            return a2.compareTo(a1);
                        }
                        return 0;
                    })
                    .sorted((x1,x2) -> {
                        if(x1.getTalkTime()==null)
                            return -1;
                        return 1;
                    })
                    .sorted((p1,p2)->  {
                        if(p1.getTalkTime()==null|| p2.getTalkTime() == null)
                            return -1;
                        return p2.getTalkTime().compareTo(p1.getTalkTime());
                    })
                    .collect(Collectors.toList());

            view2 = view2.stream()
                    .sorted((x1,x2) -> {
                        Integer a1 = null;
                        Integer a2 = null;
                        try {
                            Optional<String> num1 = Optional.ofNullable(x1.getCallNumber());
                            Optional<String> num2 = Optional.ofNullable(x2.getCallNumber());
                            if(num1.isPresent() && num2.isPresent()){
                                a1 = Integer.parseInt(num1.get());
                                a2 = Integer.parseInt(num2.get());
                            }
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                            logger.error("转整型异常",e);
                        }
                        if (a1!=null){
                            return  a1.compareTo(a2);
                        }else if(a2!=null){
                            return a2.compareTo(a1);
                        }
                        return 0;
                    })
                    .sorted((x1,x2) -> {
                        if(x1.getTalkTime()==null)
                            return -1;
                        return 1;
                    })
                    .sorted((p1,p2)->  {
                        if(p1.getTalkTime()==null|| p2.getTalkTime() == null)
                            return -1;
                        return p2.getTalkTime().compareTo(p1.getTalkTime());
                    })
                    .collect(Collectors.toList());

            views.addAll(view1);
            views.addAll(view2);
            Iterator itr = linkedList.iterator();
            while (itr.hasNext()){
                if(views.contains(itr.next())){
                    itr.remove();
                }
            }
            views.addAll(linkedList);
            views = views.stream().limit(60).collect(Collectors.toList());
        }
        return views;
    }
    
    //ip转地址淘宝接口
    public  Map<String,Object>  geIpAddresByIp(String  ip){
        Map<String, String> parameters = new HashMap<>();
       // parameters.put("ip", "36.48.77.239");
        parameters.put("ip",ip);
        logger.info("淘宝ip转换接口Url==>{}", "http://ip.taobao.com/service/getIpInfo.php");
        String result = HttpUtils.sendPost("http://ip.taobao.com/service/getIpInfo.php", parameters);
        logger.info("淘宝ip转换接口==>{}",result);
       Map<String, Object>  mao = null;
        if(!StringUtils.isEmpty(result)) {
            JSONObject jsonObject = JSON.parseObject(result);
            if (Integer.valueOf(jsonObject.get("code").toString())==0) {
                mao =  (Map<String, Object>) jsonObject.get("data");
            }
        }
        return mao;
    }

    /**
     * 更新通话记录表手机归属地
     * @param info
     */
    @Transactional
    public void updateMobileAddr(CallLoanContactsInfo info){
        contactsInfoMapper.setMobileAddr(info);
    }
    
    public CallLoanContactsInfo selectCallLoanContactsInfoByuId(String id){
        return contactsInfoMapper.selectById(id);
    }

    /**
     * 更新通讯录手机归属地
     * @param info
     */
    @Transactional
    public void updateMobileAddr(CallLoanCallInfo info){
        callLoanCallInfoMapper.setMobileAddr(info);
    }
    
    public CallLoanCallInfo selectCallLoanCallInfoByuId(String id){
        return  callLoanCallInfoMapper.selectById(id);
    }
}
